
/*
 * @Author: your name
 * @Date: 2021-06-30 16:23:10
 * @LastEditTime: 2021-07-15 22:29:01
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \server\tcp_server_libevent.h
 */

#ifndef GENERAL_TCPSERVER_H
#define GENERAL_TCPSERVER_H

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#ifdef linux
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#define EVENT__HAVE_PTHREADS
#endif

extern  "C"{
    #include "event2/bufferevent.h"
    #include "event2/buffer.h"
    #include "event2/listener.h"
    #include "event2/util.h"
    #include "event2/event.h"
    #include "event2/thread.h"
    #include <stdint.h>
};

#include <iostream>
#include <mutex>
#include <thread>
#include <map>


#define Qt_Support


#ifdef Qt_Support
#include <QObject>
#include <QDebug>

#endif
using  namespace std;

class TcpServerLibevent;
// tcp 连接

#ifdef Qt_Support
class ConnectionLibevent : public QObject {
    Q_OBJECT
#else
class ConnectionLibevent{
#endif
public:
    ConnectionLibevent(TcpServerLibevent *p,
        struct bufferevent*v,
        uint32_t fd,
        struct sockaddr_in *p1);
    ConnectionLibevent(struct bufferevent*v,
        uint32_t fd,
        struct sockaddr_in *p1);
    virtual int OnRecv(char *p,uint32_t len);  // 接收到
    virtual int OnClose(); // 接收到
    virtual int OnWrite();
    int WriteData(const char *p,uint16_t len);
    int SetServer(TcpServerLibevent *);
    TcpServerLibevent *Server();
    string IpAddress();
    uint32_t SocketFd();
private:
    int m_bytes_send;
    int m_bytes_recv;
    TcpServerLibevent *m_parent_server;
    struct bufferevent *m_event;
    struct sockaddr_in *m_addr;
    uint32_t m_fd;

};

// 管理服务端
#ifdef Qt_Support
class TcpServerLibevent : public QObject{
    Q_OBJECT
#else
class TcpServerLibevent {
#endif

typedef enum{
    RUNNING,
    STOP,
    FAIL
}SERVER_STATUS;
public:
    typedef ConnectionLibevent* (*OnAccept)(struct bufferevent *ev,uint32_t fd,struct sockaddr_in *p1);
    TcpServerLibevent(int port,string bindip);
    SERVER_STATUS Status();
    ~TcpServerLibevent();
    int StartServerSync(); //  同步启动服务器
    int StartServerAsync(); // 异步启动服务
    int StopServer();
    int RemoveConnection(uint32_t );
    int SetNewConnectionHandle(OnAccept );
    friend void cb_listener(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *addr, int len, void *ptr);
    friend void read_cb(struct bufferevent *bev, void *arg);
    friend void event_cb(struct bufferevent *bev, short events, void *arg);
    friend void write_cb(struct bufferevent *bev, void *arg);
    friend void server_run(TcpServerLibevent *p);

#ifdef Qt_Support
signals:
    int on_onnected(string ip,uint sock);
    int on_disconected(string ip,uint sock);
    int on_conn_read(string ip);

#endif
private:
    uint32_t  m_port;  // 监听端口号
    string  m_bind_ip;  // 绑定端口号
    int m_current_conection; //  当前连接数目
    uint16_t m_backlog;
    struct sockaddr_in m_server_addr;  // 服务器地址
    struct event_base * m_event_base;
    struct evconnlistener* m_event_listener;  
    SERVER_STATUS m_status;
    std::thread *m_thread;
    map<uint32_t,ConnectionLibevent*> m_map_client;
    OnAccept m_handle_accept;
    int AddConnection(uint32_t fd,ConnectionLibevent *p);

};


#endif
